package org.jiucai.cas.auth;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.jiucai.appframework.base.spring.helper.SpringHelper;
import org.jiucai.appframework.base.util.IpUtil;
import org.jiucai.appframework.common.util.LogUtil;
import org.jiucai.appframework.common.util.Logs;
import org.springframework.beans.factory.annotation.Autowired;

import org.jiucai.cas.auth.service.AuthCheckService;
import org.jiucai.cas.auth.service.AuthResultService;

/**
 * 应用权限检查过滤器
 * 
 * @author zhaidw
 * 
 */
public class AuthCheckFilter implements Filter {

	private Logs log = LogUtil.getLog(getClass());
	private String[] ignoreExts;
	private String[] ignorePages;
	
	@Autowired
	protected AuthCheckService authCheckService;
	
	@Autowired
	protected AuthResultService authResultService;
	
	
	
	

	public AuthCheckService getAuthCheckService() {
		
		return authCheckService;
	}

	public void setAuthCheckService(AuthCheckService authCheckService) {
		this.authCheckService = authCheckService;
	}

	public AuthResultService getAuthResultService() {
		return authResultService;
	}

	public void setAuthResultService(AuthResultService authResultService) {
		this.authResultService = authResultService;
	}

	public AuthCheckFilter() {

	}

	@Override
	public void init(FilterConfig config) throws ServletException {

		log.info("AuthCheckFilter inited.");

		String exts = config.getInitParameter("ignore-exts");
		if (StringUtils.isNotEmpty(exts) || StringUtils.isNotBlank(exts)) {
			log.info("找到配置 ignore-exts 忽略校验扩展名 " + exts);
			ignoreExts = exts.split(",");
		}

		String pages = config.getInitParameter("ignore-pages");
		if (StringUtils.isNotEmpty(pages) || StringUtils.isNotBlank(pages)) {
			log.info("找到配置 ignore-pages 忽略校验页面 " + pages);
			ignorePages = pages.split(",");
		}

	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse res,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		String uri = request.getRequestURI();
		//String queryString = request.getQueryString() == null ? "" : request.getQueryString();

		if (null != uri) {
			int extPos = uri.lastIndexOf(".");
			String ext = "";
			if (extPos > -1) {
				ext = uri.substring(extPos + 1, uri.length());
				for (int i = 0; i < ignoreExts.length; i++) {
					if (ext.equals(ignoreExts[i])) {
						chain.doFilter(request, response);
						// log.debug("匹配到资源 {} 忽略校验扩展名 {} ", uri , ext);
						return;
					}
				}
			}

			for (int i = 0; i < ignorePages.length; i++) {
				if (uri.endsWith(ignorePages[i])) {
					chain.doFilter(request, response);
					log.debug("匹配到资源: " + uri + " 忽略校验页面: " + ignorePages[i]);
					return;
				}
			}
		}

		//log.info("RequestURI: " + uri + ", QueryString: " + queryString);
		
		
		
		if(null == authCheckService){
			log.debug("authCheckService 注入失败，通过上下文获取...");
			authCheckService = SpringHelper.getApplicationContext(request).getBean("authCheckService", AuthCheckService.class);
		}
		

		Boolean isLogin = authCheckService.isLogin();

		if (isLogin) {
			//log.info("当前登录的用户: " + UserUtil.getUser().getLoginName());

		} else {
			log.debug("当前用户[" + IpUtil.getIp(request) + "] 未登录");
		}

		// 如果已登录则继续请求
		if (isLogin) {
			chain.doFilter(request, response);
		} else {
			String referer = request.getHeader("Referer");
			String failedMsg = "";
			if (StringUtils.isBlank(referer)) {
				failedMsg = "未授权的访问，请登录后再进行操作。";
			} else {
				failedMsg = "会话已过期，请重新登录。";

				//为处理会话过期：异步请求请求时而设置的特殊超时标记
				response.setHeader("sessionStatus", "timeout"); 
			}

			request.setAttribute("failed_msg", failedMsg);
			
			if(null == authResultService){
				log.debug("authResultService 注入失败，通过上下文获取...");
				authResultService = SpringHelper.getApplicationContext(request).getBean("authResultService", AuthResultService.class);
			}
			
			authResultService.onLoginFailed(request, response);

		}

	}

	@Override
	public void destroy() {

	}
}
